package org.anyin.gitee.cloud.lib.core.web.serializer;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import lombok.extern.slf4j.Slf4j;
import org.anyin.gitee.cloud.lib.core.enums.BaseEnum;

import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;

@Slf4j
@JacksonStdImpl
public class StringAsDictDeserializer extends JsonDeserializer<BaseEnum> implements ContextualDeserializer {

    public StringAsDictDeserializer(){}

    private Class<?> clazz;

    public StringAsDictDeserializer(Class<?> clazz){
        this.clazz = clazz;
    }

    @Override
    public BaseEnum deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
        String value = p.getValueAsString();
        BaseEnum type = Arrays.stream(clazz.getEnumConstants()).map(t -> (BaseEnum) t)
                .filter(t -> Objects.equals(t.getCode(), value))
                .findAny().orElse(null);
        if(type == null){
            throw new DictSerializerException("value is error, not found enum type");
        }
        return type;
    }

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
        Class<?> typeClazz = property.getType().getRawClass();
        return new StringAsDictDeserializer(typeClazz);
    }
}
